/*
    nspire-gamekit - a simple homebrew game framework
    Copyright (C) 2011  Daniel Tang

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

extern "C" {
    #include <os.h>
}
#include "ndlesscpp.h"
#include "gameloop.h"
#include "types/gameloop.h"
#include "timer.h"
#include "debug.h"

static int exitRequest;
static int exitCode;

int gameLoopRun(NGKGame* gameHandler, unsigned int fps) {
    // Lets set up our timers
    volatile unsigned *timerVal = (unsigned*)0x900D0000;
	volatile unsigned *timerDivider = (unsigned*)0x900D0004;
	volatile unsigned *timerControl = (unsigned*)0x900D0008;
    
    unsigned timerOriginalVal = *timerVal;
    unsigned timerOriginalDivider = *timerDivider;
    unsigned timerOriginalControl = *timerControl;
    
    *timerControl = (*timerControl & 0xFFFFFFE0) | 0xF; //Indefinitely increasing timer
    *timerDivider = 31; //Ticks every 1ms. Therefore timer resolution is 1ms
    *timerVal = 0;
    NGKGameTime gameTime = 0;
    //Finished setting up game timers
    
    exitCode = gameHandler->init();
    exitRequest = (exitCode != 0);
    
    while (!exitRequest) { 
        unsigned timeDifference = *timerVal;
        if (timeDifference > 0) {
            *timerVal = 0;
            gameTime += timeDifference;
            gameTimerTick(timeDifference);
        }
        idle();
    }
    
    
    //Restore timers
    *timerVal = timerOriginalVal;
    *timerDivider = timerOriginalDivider;
    *timerControl = timerOriginalControl;
    
    return exitCode;
}

void gameLoopExit(int code) {
    exitCode = code;
    exitRequest = true;
}